﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BOSTools.DirectoryManifestGenerator;
using System.IO;
using NullFX.Security;

namespace DirectoryManifestTest
{
    /// <summary>
    /// Summary description for IntegrationTests
    /// </summary>
    [TestClass]
    public class IntegrationTests
    {
        public IntegrationTests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void Integration_TwoSubdirsOneFileEach()
        {
            string sourceDir = Path.Combine(TestContext.TestDeploymentDir, "Integration_TwoSubdirsOneFileEach");

            string[] paths = new string[]
            {
                "0.txt",
                @"1\1.txt",
                @"2\2.txt"
            };

            Directory.CreateDirectory(sourceDir);
            Directory.CreateDirectory(Path.Combine(sourceDir, "1"));
            Directory.CreateDirectory(Path.Combine(sourceDir, "2"));
            File.Copy(Path.Combine(TestContext.TestDeploymentDir, "StaticVersionAssembly.dll"), Path.Combine( sourceDir, "StaticVersionAssembly.dll"));

            foreach (string path in paths)
            {
                TestHelper.WriteText(Path.Combine( sourceDir, path), path);
            }

            string outputFile = Path.Combine(TestContext.TestDir, "Integration_TwoSubdirsOneFileEach.xml");
            DirectoryManifestController controller = new DirectoryManifestController(sourceDir, outputFile);

            controller.Process();
            Assert.IsTrue(File.Exists(outputFile), "File {0} not created successfully", outputFile);

            DirectoryManifest manifest = XmlManifestReader.Load(outputFile);

            Assert.AreEqual(sourceDir, manifest.DirectoryName, true);
            Assert.AreEqual(4, manifest.TotalFiles, "Total Files mismatch");
            foreach (string path in paths)
            {
                Assert.IsTrue(manifest.ContainsFile(path), "Path {0} not found in manifest", path);
            }

            FileDetail detail = manifest.FindRelativeFileName("StaticVersionAssembly.dll");
            Assert.IsNotNull(detail);

            Assert.AreEqual("5.6.7.8", detail.FileVersion.ToString(), "File version check failed");
            Assert.AreEqual("5.6.7.8", detail.ProductVersion.ToString(), "Product version check failed");
            
            detail = manifest.FindRelativeFileName(@"1\1.txt");
            Assert.IsNotNull(detail);
            Assert.AreEqual("D7EE7678", detail.Checksum, "Checksum mismatch");


            Assert.IsNull(manifest.FindRelativeFileName("NonexistentFileName.dll"));
            Assert.IsFalse(manifest.ContainsFile("NonexistentFileName.dll"));

            Assert.IsTrue( manifest.ContainsDirectory( "1" ));
            Assert.IsTrue( manifest.ContainsDirectory( "2" ));
            Assert.IsFalse( manifest.ContainsDirectory( "" ));
            Assert.IsFalse( manifest.ContainsDirectory( "3" ));
        }
    }
}
